import time
import uuid

from flask import request
from sqlalchemy import func

from constant.BlogConstant import BlogConstant
from entity.models import db, Comment, Page
from service.ArticleService import get_service_article_by_uuid, update_article_comment_count
from service.UserService import get_user_by_uuid
from util.LoginUtil import get_login_info


def get_comments_by_uuid(uuid):
    parent_comment = db.session.query(Comment).filter(Comment.reference_uuid == uuid) \
        .filter(Comment.status == BlogConstant.publish_status).first()
    if parent_comment is None:
        return []
    else:
        child_comment = db.session.query(Comment).filter(parent_comment.uuid == Comment.reference_uuid) \
            .filter(Comment.status == BlogConstant.publish_status).all()
        comments = [parent_comment, child_comment]
        return comments


def assemble_comment_contact():
    comment = Comment()
    user_uuid = get_login_info()["user"]["uuid"]
    comment.status = BlogConstant.pending_status
    comment.create_at = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    comment.create_by = user_uuid
    comment.update_at = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    comment.update_by = user_uuid
    comment.uuid = uuid.uuid4()
    # concat 头一次添加，设置为 concat_first
    comment.reference_uuid = BlogConstant.comment_contact_first
    comment.message = request.json['content']
    comment.to_reference = str(request.json['comments'])
    comment.down = 0
    comment.up = 0
    comment.reference_type = BlogConstant.comment_type_contact
    return comment


def save_comment(comment):
    db.session.add(comment)
    db.session.commit()
    db.session.close()


def get_contact_comment():
    result = []
    parent_comments = db.session.query(Comment).filter(
        Comment.reference_type == BlogConstant.comment_type_contact) \
        .filter(Comment.status == BlogConstant.publish_status) \
        .filter(Comment.reference_uuid == BlogConstant.comment_contact_first).all()
    if parent_comments is None:
        return []
    for comment in parent_comments:
        user = get_user_by_uuid(comment.create_by)
        root = {"name": user.nick_name, "time": comment.create_at, "content": comment.message,
                "avatar": user.avatar, "comment_uuid": comment.uuid, "user_uuid": user.uuid}
        child_comments = db.session.query(Comment) \
            .filter(comment.uuid == Comment.reference_uuid) \
            .filter(Comment.status == BlogConstant.publish_status) \
            .filter(Comment.reference_type == BlogConstant.comment_type_contact).all()
        root["comments"] = []
        for child_comment in child_comments:
            user = get_user_by_uuid(child_comment.create_by)
            root["comments"].append(
                {"name": user.nick_name, "time": child_comment.create_at, "content": child_comment.message,
                 "avatar": user.avatar, "comment_uuid": comment.uuid, "user_uuid": user.uuid})
        result.append(root)
    return result


def get_article_comment(uuid):
    result = []
    parent_comments = db.session.query(Comment).filter(
        Comment.reference_type == BlogConstant.comment_type_article) \
        .filter(Comment.status == BlogConstant.publish_status) \
        .filter(Comment.reference_uuid == uuid).all()
    if parent_comments is None:
        return []
    for comment in parent_comments:
        user = get_user_by_uuid(comment.create_by)
        root = {"name": user.nick_name, "time": comment.create_at, "content": comment.message,
                "avatar": user.avatar, "comment_uuid": comment.uuid, "user_uuid": user.uuid}
        child_comments = db.session.query(Comment).filter(comment.uuid == Comment.reference_uuid) \
            .filter(Comment.status == BlogConstant.publish_status) \
            .filter(Comment.reference_type == BlogConstant.comment_type_article).all()
        root["comments"] = []
        for child_comment in child_comments:
            user = get_user_by_uuid(child_comment.create_by)
            root["comments"].append(
                {"name": user.nick_name, "time": child_comment.create_at, "content": child_comment.message,
                 "avatar": user.avatar, "comment_uuid": comment.uuid, "user_uuid": user.uuid})
        result.append(root)
    return result


def assemble_article_comment():
    comment = Comment()
    user_uuid = get_login_info()["user"]["uuid"]
    comment.status = BlogConstant.pending_status
    comment.create_at = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    comment.create_by = user_uuid
    comment.update_at = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    comment.update_by = user_uuid
    comment.uuid = uuid.uuid4()
    comment.reference_uuid = request.json['uuid']
    comment.message = request.json['content']
    comment.to_reference = ''
    comment.down = 0
    comment.up = 0
    comment.reference_type = BlogConstant.comment_type_article
    return comment


def assemble_reply_comment():
    comment = Comment()
    user_uuid = get_login_info()["user"]["uuid"]
    comment.status = BlogConstant.pending_status
    comment.create_at = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    comment.create_by = user_uuid
    comment.update_at = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    comment.update_by = user_uuid
    comment.uuid = uuid.uuid4()
    comment.reference_uuid = request.json['item']['comment_uuid']
    comment.message = request.json['message']
    comment.to_reference = request.json['item']['user_uuid']
    comment.down = 0
    comment.up = 0
    if request.json['flag']:
        comment.reference_type = BlogConstant.comment_type_article
        article = get_service_article_by_uuid(request.json['article_uuid'])
        update_article_comment_count(article)
    else:
        comment.reference_type = BlogConstant.comment_type_contact
    return comment


def get_comment_page(page):
    if page == '' or page is None:
        page = 0
    total = db.session.query(func.count(Comment.uuid)).scalar()
    elements = db.session.query(Comment).order_by(
        Comment.create_at.desc()).limit(BlogConstant.page_size).offset(
        (page - 1) * BlogConstant.page_size)
    db.session.close()
    elements = list(elements)
    return Page(page, BlogConstant.page_size, total, elements)


def delete_comment(uuid, page):
    comment = db.session.query(Comment).filter(Comment.uuid == uuid).first()
    comment.status = BlogConstant.delete_status
    db.session.commit()
    return get_comment_page(page)


def publish_comment(uuid, page):
    comment = db.session.query(Comment).filter(Comment.uuid == uuid).first()
    comment.status = BlogConstant.publish_status
    db.session.commit()
    return get_comment_page(page)
